<template xlang="wxml" minapp="mpvue">
    <view class="tki-tree" @touchmove.stop="">
        <view class="tki-tree-mask" :class="{ show: showTree }" @tap="_cancel"></view>
        <view class="tki-tree-cnt" :class="{ show: showTree }">
            <view class="tki-tree-bar">
                <view class="tki-tree-bar-cancel" :style="{ color: cancelColor }" hover-class="hover-c" @tap="_cancel">取消</view>
                <view class="tki-tree-bar-title" :style="{ color: titleColor }">{{ title }}</view>
                <view class="tki-tree-bar-confirm" :style="{ color: confirmColor }" hover-class="hover-c" @tap="_confirm">确定</view>
            </view>
            <view class="tki-tree-view">
                <scroll-view class="tki-tree-view-sc" :scroll-y="true">
                    <block v-for="(item, index) in treeList" :key="index">
                        <view
                            class="tki-tree-item"
                            :style="[
                                {
                                    paddingLeft: item.rank * 15 + 'px',
                                    zIndex: item.rank * -1 + 50
                                }
                            ]"
                            :class="{
                                border: border === true,
                                show: item.show,
                                last: item.lastRank,
                                showchild: item.showChild
                            }"
                        >
                            <view class="tki-tree-label" @tap.stop="_treeItemTap(item, index)">
                                <image class="tki-tree-icon" :src="item.lastRank ? lastIcon : item.showChild ? currentIcon : defaultIcon"></image>
                                {{ item.name }}
                            </view>
                            <!-- 	<view class="tki-tree-check" @tap.stop="_treeItemSelect(item, index)" v-if="selectParent?true:item.lastRank"> -->
                            <view class="tki-tree-check" @tap.stop="_treeItemSelect(item, index)">
                                <view class="tki-tree-check-yes" v-if="item.checked" :class="{ radio: !multiple }" :style="{ 'border-color': confirmColor }">
                                    <view class="tki-tree-check-yes-b" :style="{ 'background-color': confirmColor }"></view>
                                </view>
                                <view class="tki-tree-check-no" v-else :class="{ radio: !multiple }" :style="{ 'border-color': confirmColor }"></view>
                            </view>
                        </view>
                    </block>
                </scroll-view>
            </view>
        </view>
    </view>
</template>

<script>
export default {
    name: 'tki-tree',
    props: {
        clear: {
            type: Boolean,
            default: false
        },
        range: {
            type: Array,
            default: function() {
                return [];
            }
        },
        rangeKey: {
            type: String,
            default: 'label'
        },
        title: {
            type: String,
            default: ''
        },
        multiple: {
            // 是否可以多选
            type: Boolean,
            default: true
            // default: true
        },
        selectParent: {
            //是否可以选父级
            type: Boolean,
            default: false
        },
        confirmColor: {
            // 确定按钮颜色
            type: String,
            default: '' // #07bb07
        },
        cancelColor: {
            // 取消按钮颜色
            type: String,
            default: '' // #757575
        },
        titleColor: {
            // 标题颜色
            type: String,
            default: '' // #757575
        },
        currentIcon: {
            // 展开时候的ic
            type: String,
            default:
                ''
        },
        defaultIcon: {
            // 折叠时候的ic
            type: String,
            default:
                ''
        },
        lastIcon: {
            // 没有子集的ic
            type: String,
            default: ''
        },
        border: {
            // 是否有分割线
            type: Boolean,
            default: false
        }
    },
    data() {
        return {
            showTree: false,
            treeList: [],
            selectIndex: -1
        };
    },
    computed: {},
    methods: {
        _show() {
            this.showTree = true;
        },
        _hide() {
            this.showTree = false;
        },
        _cancel() {
            this._hide();
            this.$emit('cancel', '');
        },
        _confirm() {
            // 处理所选数据
            let rt = [],
                obj = {};
            this.treeList.forEach((v, i) => {
                if (this.treeList[i].checked) {
                    obj = {};
                    obj.parents = this.treeList[i].parents;
                    obj = Object.assign(obj, this.treeList[i].source);
                    // 移除子元素
                    delete obj.children;
                    rt.push(obj);
                }
            });
            this._hide();
            console.log('rt', rt);
            this.$emit('confirm', rt);
        },
        //扁平化树结构
        _renderTreeList(list = [], rank = 0, parentId = [], parents = []) {
            if (this.clear && rank === 0) {
                this.treeList = [];
            }

            list.forEach(item => {
                this.treeList.push({
                    id: item.id,
                    name: item[this.rangeKey],
                    source: item,
                    parentId, // 父级id数组
                    parents, // 父级id数组
                    rank, // 层级
                    showChild: false, //子级是否显示
                    show: rank === 0, // 自身是否显示
                    checked: false
                });
                if (Array.isArray(item.children) && item.children.length > 0) {
                    // console.log(item)
                    let parentid = [...parentId],
                        parentArr = [...parents];
                    delete parentArr.children;
                    parentid.push(item.id);
                    parentArr.push({ id: item.id, [this.rangeKey]: item[this.rangeKey] });
                    this._renderTreeList(item.children, rank + 1, parentid, parentArr);
                } else {
                    this.treeList[this.treeList.length - 1].lastRank = true;
                }
            });
            if (rank === 0) {
                this.$forceUpdate();
            }
        },
        // 点击
        _treeItemTap(item, index) {
            if (item.lastRank === true) {
                //点击最后一级时触发事件
                this.treeList[index].checked = !this.treeList[index].checked;
                this._fixMultiple(index);
                return;
            }
            let list = this.treeList;
            let id = item.id;
            item.showChild = !item.showChild;
            list.forEach((childItem, i) => {
                if (item.showChild === false) {
                    //隐藏所有子级
                    if (!childItem.parentId.includes(id)) {
                        return;
                    }
                    if (childItem.lastRank !== true) {
                        childItem.showChild = false;
                    }
                    childItem.show = false;
                } else {
                    if (childItem.parentId[childItem.parentId.length - 1] === id) {
                        childItem.show = true;
                    }
                }
            });
            // console.log(this.treeList)
        },
        _treeItemSelect(item, index) {
            this.treeList[index].checked = !this.treeList[index].checked;
            this._fixMultiple(index);
        },
        // 处理单选多选
        _fixMultiple(index) {
            if (!this.multiple) {
                // 如果是单选
                this.treeList.forEach((v, i) => {
                    if (i != index) {
                        this.treeList[i].checked = false;
                    }
                });
            }
        },
        // 重置数据
        _reTreeList() {
            this.treeList.forEach((v, i) => {
                this.treeList[i].checked = false;
            });
        }
    },
    watch: {
        range(list) {
            this._renderTreeList(list);
        },
        multiple() {
            if (this.range.length) {
                this._reTreeList();
            }
        },
        selectParent() {
            if (this.range.length) {
                this._reTreeList();
            }
        }
    },
    mounted() {}
};
</script>

<style scoped>
@import 'style.css';
</style>
